import {ElTooltip} from 'element-plus';
import styles from "./index.module.scss";
import type {Arrow, Point, RectanglePointData, Toolbars,RoiData,DrawStatusType} from "@/views/roi/type";
import {DRAWING_TEXT, DrawStatus, DrawType, DrawTypeCN,CLOSE_SVG} from "@/views/roi/config";
import VIcon from "@/components/vIcon/index.vue";
// @ts-ignore
import {v4} from "uuid";


const RoiComponent = defineComponent({
    setup() {
        // canvas实例
        const roiCanvas = ref<HTMLCanvasElement>();
        // 绘图上下文
        const ctx = ref<CanvasRenderingContext2D | undefined>();
        // 画图类型
        const drawType = ref<DrawType>()
        // 画图的颜色
        const drawColor = ref('');
        // 画图状态
        const drawStatus = ref<DrawStatusType>(DrawStatus.BEFORE_DRAW);
        // 画图状态
        const autoDraw = ref(false);
        // ResizeObserver 对象 监视 Element 内容盒或边框盒或者 SVGElement 边界尺寸的变化
        const observer = ref<ResizeObserver | undefined>();
        // 存储 canvas 的宽高
        const canvasSize = reactive({
            width: 1200,
            height: 800
        })
        // 矩形不带箭头
        const rectanglePointData = reactive<RectanglePointData>({ // 矩形左上角与右下角坐标
            leftTopPoint: {x: 0, y: 0},
            rightBottomPoint: {x: 0, y: 0}
        });
        // 用于保存roi数据
        const saveRoiData = reactive<RoiData[]>([]);
        const toolbars = reactive<Toolbars[]>([
            {
                name: 'rectangle',
                title: '矩形',
                drawType: 'RECTANGLE',
                drawColor: '#4639C1'
            },
            {
                name: 'polygon',
                title: '多边形',
                drawType: 'POLYGON',
                drawColor: '#E17008'
            },
            {
                name: 'trip-line',
                title: '绊线',
                drawType: 'PartnerLine',
                drawColor: '#0379E5'
            },
            {
                name: 'rectangle-arrow',
                title: '有向矩形',
                drawType: 'RECT_ARROW',
                drawColor: '#D80C18'
            },
            {
                name: 'polygon-arrow',
                title: '有向多边形',
                drawType: 'POLYGON_ARROW',
                drawColor: '#7D0DE2'
            },
            {
                name: 'arrow-line',
                title: '箭头',
                drawType: 'ARROW',
                drawColor: '#13AC3E'
            },
            {
                name: 'clear',
                title: '清空',
                drawType: 'CLEAR',
            },
            {
                name: 'save',
                title: '保存',
                drawType: 'SAVE',
            },
        ])

        /**
         * canvas 初始化
         */
        const fnInit = () => {
            // roiCanvas.value = getCurrentInstance()?.refs['roi-canvas'] as HTMLCanvasElement;
            if (!roiCanvas.value) return debugWarn('roiCanvas值为空');
            ctx.value = roiCanvas.value.getContext('2d') as CanvasRenderingContext2D;
            const {clientHeight, clientWidth} = roiCanvas.value;
            canvasSize.width = clientWidth;
            canvasSize.height = clientHeight;
            //  TODO:坐标转换  当canvas大小发生变化时，进行坐标转换
        }
        /**
         * 错误提示
         */
        const debugWarn = (str: string) => {
            console.log('\x1B[36m%s\x1B[0m', str)
        }
        /**
         * uuid
         */
        const uuid = () => {
            return v4();
        };
        /**
         * 深拷贝
         */
        const deepClone = (data:any) => {
            try {
                return JSON.parse(JSON.stringify(data));
            }catch (e:any) {
                debugWarn(e)
            }
        }
        /**
         * 绘制中提示
         */
        const drawingNotice = () => {
            if (!ctx.value) return debugWarn('ctx值为空');
            // 在绘制之前保存当前绘图上下文的状态
            ctx.value.save();
            ctx.value.font = `16px Arial,Microsoft YaHei`;
            ctx.value.textBaseline = 'middle';
            ctx.value.shadowColor = 'rgba(0,0,0,0.3)'
            ctx.value.shadowBlur = 1
            ctx.value.shadowOffsetY = 2;
            ctx.value.fillStyle = '#ff0000';
            const text = DRAWING_TEXT.replace("@", drawType.value ? DrawTypeCN[drawType.value] : '');
            ctx.value.fillText(text, 14, 20);
            // 通过在绘图状态栈中弹出顶端的状态，将 canvas 恢复到最近的保存状态的方法。
            // 如果没有保存状态，此方法不做任何改变。
            ctx.value.restore()
        }
        /**
         * 获取矩形4个顶点坐标
         */
        const getRectanglePoints = (leftTopPoint: Point, rightBottomPoint: Point, type: DrawType.RECT_ARROW | DrawType.RECTANGLE) => {
            const points: Point[] = [];
            const {x: offsetX1, y: offsetY1} = leftTopPoint;
            const {x: offsetX2, y: offsetY2} = rightBottomPoint;
            const direction: Arrow = {
                left: false,
                right: false
            }
            if (type === DrawType.RECTANGLE) {
                points.push(leftTopPoint);
                points.push({x: offsetX1, y: offsetY2});
                points.push(rightBottomPoint);
                points.push({x: offsetX2, y: offsetY1});
            } else {
                points.push({...leftTopPoint, ...direction});
                points.push({x: offsetX1, y: offsetY2, ...direction});
                points.push({...rightBottomPoint, ...direction});
                points.push({x: offsetX2, y: offsetY1, ...direction});
            }
            return points;
        }
        /**
         * 获取右上角的点
         */
        const getMaxPoint = (points: Point[]) => {
            let max: Point = {x: 0, y: 0};
            for (let i = 0; i < points.length; i++) {
                const {x} = points[i];
                // 找到最大值// 找到x最大并且y最小的那个
                if (max.x <= x) {
                    Object.assign(max, points[i]);
                }
            }
            return max;
        };
        /**
         * 创建关闭按钮
         */
         const createCloseBtn = (left: number, top: number, id: string) => {
            const closeDom = document.createElement('div')
            closeDom.setAttribute('class', 'close');
            closeDom.setAttribute('id', id);
            closeDom.setAttribute('style', `cursor: pointer;position: absolute;top: ${top}px;left: ${left}px; transform: translate(-50%, -50%); width: 20px; height: 20px;`);
            return closeDom
        };
        /**
         * 创建关闭按钮
         */
         const createCloseSVG = (id: string) => {
            const svgDom = new DOMParser().parseFromString(CLOSE_SVG, 'image/svg+xml').documentElement;
            svgDom.addEventListener('click', (function () {
                // TODO:清空选中的roi
                // deleteRoiById(id);
                svgDom.removeEventListener("click", () => {
                });
                svgDom.remove();
            }).bind(svgDom))
            return svgDom
        };
        /**
         * 创建并挂载节点
         */
         const createAndMountCloseBtn = (mostMax: Point, id: string) => {
            const isExist = document.getElementById(`${id}`);
            if (!isExist) {
                const dom = createCloseBtn(mostMax.x, mostMax.y, id);
                const svgDom = createCloseSVG(id);
                dom.appendChild(svgDom);
                // TODO:这里需要处理
                document.querySelector('.galaxy-roi-container')?.appendChild(dom)
            }
        };
        /**
         * svg 点击事件分类
         */
        const fnClick = (e: Event, row: Toolbars) => {
            e.preventDefault()
            if (Object.keys(DrawType).includes(row.drawType)) {
                autoDraw.value = true;
                drawType.value = row.drawType as DrawType;
            }
            drawColor.value = row.color ?? '';
            drawingNotice();
            switch (row.drawType) {
                case 'RECTANGLE'://矩形

                    break;
                case 'CLEAR':
                    break;
                default:
                    break;
            }
        }
        /**
         * 鼠标按下
         */
        const onMouseDownHandel = (e: MouseEvent) => {
            const {offsetX: x, offsetY: y, buttons} = e;
            //    左键绘制
            if (buttons === 1) {
                drawStatus.value = DrawStatus.DRAWING;// 绘制中
                if (!drawType.value) return debugWarn('drawType值为空');
                if (drawType.value === DrawType.RECTANGLE) {// 矩形不带箭头
                    rectanglePointData.leftTopPoint = {x, y};
                }
            }
            //     右键结束绘制
            if (buttons === 2) {
                const id: string = uuid();
                if (drawType.value === DrawType.RECTANGLE) {// 矩形不带箭头
                    // 退出时保存绘制的图形到存储数据中
                    const {x: offsetX1, y: offsetY1} = rectanglePointData.leftTopPoint
                    const {x: offsetX2, y: offsetY2} = rectanglePointData.rightBottomPoint

                    if (offsetX1 !== 0 || offsetY1 !== 0 || offsetX2 !== 0 || offsetY2 !== 0) {
                        const points = getRectanglePoints(rectanglePointData.leftTopPoint, rectanglePointData.rightBottomPoint, DrawType.RECTANGLE)
                        saveRoiData.push({type: DrawType.RECTANGLE, points, color: drawColor.value, id})
                        // 保存完后清空现在的数据
                        rectanglePointData.leftTopPoint = {x: 0, y: 0}
                        rectanglePointData.rightBottomPoint = {x: 0, y: 0}
                        // 绘制dom
                        const max: Point = getMaxPoint(deepClone(points)); // 找到最右上角的点的坐标
                        createAndMountCloseBtn(max, id);
                    }

                }
            }
        }
        /**
         * 退出并保存
         */
        const quitAndSaveROI = (e?: Event) => {
            e?.preventDefault()
            //  TODO: 保存roi
        }

        onMounted(() => {
            fnInit()
        })


        return () => (
            <div
                class={styles.galaxyRoiContainer}
                onClick={(e: Event) => {
                    e.preventDefault()
                }}
                onDblclick={(e: Event) => {
                    e.preventDefault()
                }}
                onMousemove={(e: Event) => {
                    e.preventDefault()
                }}
                onContextmenu={(e: Event) => quitAndSaveROI(e)}
            >
                <canvas
                    ref={roiCanvas}
                    class={styles.galaxyRoi}
                    style={{background: drawType ? 'rgba(0, 0, 0, 0.5)' : 'rgba(0, 0, 0, 0)'}}
                    width={canvasSize.width}
                    height={canvasSize.height}
                    onMousedown={onMouseDownHandel}
                ></canvas>
                <div class={styles.galaxyRoiToolbar}>
                    {
                        toolbars.map((u) => (
                            <ElTooltip effect={'light'} content={u.title} placement={"top-start"}>
                                <VIcon
                                    name={u.name}
                                    class={'cursor-pointer'}
                                    color={u.color ?? '#fff'}
                                    size={u.size ?? '20px'}
                                    title={u.title}
                                    onClick={(e: Event) => fnClick(e, u)}
                                />
                            </ElTooltip>
                        ))
                    }
                </div>
            </div>
        )
    }
})

export default RoiComponent;